package com.geek.javase.ch18.work.work2;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/*
 *@Date 2025/11/7
 *@Author wangpeng
 *@Description
 *  * * 反射: “暴力破解”
 *  * 1.破坏封装性
 *  * 2.破坏泛型
 *  *
 *  * 需求：集合泛型为Integer，通过反射，将"abc"字符串添加至集合中
 *    已知：
 *      List<Integer> list = new ArrayList<>();
 *      list.add(10);
 *      list.add(20);
 *      list.add(30);
 *    输出结果：
 *      [10, 20, 30, abc]
 */


public class ReflectList {
    public static void main(String[] args) {
        //集合指定泛型的数据类型，在"编译期"约束添加进来的元素的数据类型
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        //list.add("abc");

        //反射（运行期的机制），会破坏泛型
        try{
            /*这行代码获取了list对象的运行时类（Class对象）。由于list是ArrayList的实例，而ArrayList实现了List接口，所以clazz是ArrayList的类对象，
            但类型被声明为Class<? extends List>，表示这是List接口的某个子类的Class对象。*/
            Class<? extends List> clazz = list.getClass();
            /*这里通过反射获取clazz所代表的类（即ArrayList）的名为"add"的方法，并且该方法接受一个参数，参数类型为Object.class。
            注意，在Java中，List的add方法参数类型是泛型的，但在反射中，由于类型擦除，在运行时add方法实际上接受的是Object类型。所以这里使用Object.class来匹配方法。
            这里调用刚才获取的add方法，在list对象上执行，并传入参数"abc"。也就是说，这行代码相当于通过反射调用了list.add("abc")。*/
            clazz.getMethod("add", Object.class).invoke(list, "abc");

            /*由于在反射中，我们通过getMethod获取方法时，使用Object.class可以匹配任何类型，因为Java中所有类都是Object的子类。
            所以这里可以成功调用add方法，并向Integer类型的List中添加了一个字符串"abc"。但是，请注意，在正常情况下，如果我们使用泛型List<Integer>，
            那么尝试添加一个字符串会导致编译错误。但是反射绕过了编译时的类型检查，所以可以在运行时添加任意类型的对象。
            这会导致在后续使用列表时可能抛出ClassCastException。*/
            /*
            绕过泛型检查：虽然list声明为List<Integer>，但反射在运行时调用，绕过了编译时的泛型检查
            类型擦除：运行时JVM不知道List<Integer>，只知道是List<Object>
            潜在问题：这会导致在后续使用列表元素时可能出现ClassCastException
            */

        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println(list);
    }
}





/*//版本2
public class ReflectList {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //集合指定泛型的数据类型，在"编译期"约束添加进来的元素的数据类型
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        //list.add("abc");

        //反射（运行期的机制），会破坏泛型

        //1.获得操作的类的类类型，即Class对象
        Class<List> clazz = List.class;
        //2.获得指定的方法add() clazz.getDeclaredMethod("add", Object.class) 其第一个参数：方法名  第二个参数：方法形参的数据类型
        Method addMethod = clazz.getDeclaredMethod("add", Object.class);;
        //3.通过反射执行  invoke(执行的对象，传递的形参数据)
        Object invokeResult = addMethod.invoke(list, "abc");
        System.out.println("invokeResult:" + invokeResult);
        System.out.println(list);
    }
}*/


